package org.knot.mockejb3.createors;

import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.naming.InitialContext;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.hibernate.SessionFactory;

/**
 * 装载 数据源
 * 
 * @author yuxiaowei
 *
 */
public class LoadConf {

    private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoadConf.class);

    private static String defaultSFKey = null;

    private static Map<String, SessionFactory> mapSessionFactory = null;
    
    /**
     * 配置文件名称
     */
    private static final String MOCKEJB3_CONFIG_FILE = "mockejb3.xml";

    // 初始化 读取config文件；
    private static void init() {
        try {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            URL url = loader.getResource(MOCKEJB3_CONFIG_FILE);
            if (url == null) {
                return;
//                throw new RuntimeException("no find mockejb3.xml File , please put mockejb3.xml in your classpath!");
            }
            loadDom(url);
            log.info(new StringBuilder().append("load mockejb3.xml config file from :").append(url.getFile()).toString());
        } catch (Exception ex) {
            log.error("mockejb3.xml loadConfig error !");
            throw new RuntimeException("mockejb3.xml loadConfig error !", ex);
        }
    }

    
    /**
     * 装载配置文件
     * 
     * @param url
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    private static void loadDom(URL url) throws Exception {
        try {
            DocumentFactory df = DocumentFactory.getInstance();
            // 取得XML路
            SAXReader reader = new SAXReader(df);
            // 获得XML文档对象
            Document document = reader.read(url);
            Element root = document.getRootElement();
            for (Iterator i = root.elementIterator(); i.hasNext();) {
                Element element = (Element) i.next();
                String tag = element.getName();
                if (tag.equalsIgnoreCase("attributes")) {

                    mapSessionFactory = new HashMap<String, SessionFactory>();

                    if (element.attribute("default") != null) {
                        defaultSFKey = element.attribute("default").getValue().trim();
                    } else {
                        throw new RuntimeException("default name can't not be null!");
                    }
                    for (Iterator sub = element.elementIterator("attribute"); sub.hasNext();) {
                        Element subElement = (Element) sub.next();
                        if (subElement.attribute("name") != null && subElement.attribute(defaultSFKey) != null) {
                            String name = subElement.attribute("name").getValue().trim();
                            String sessionFactoryKey = subElement.attribute(defaultSFKey).getValue().trim();
                            SessionFactory sf = null;
                            if ("conf".equalsIgnoreCase(defaultSFKey)) {
                                sf = org.knot.mockejb3.plugin.hibernate.HibernateHelper.getSessionFactory(sessionFactoryKey);
                            } else if ("jndi".equalsIgnoreCase(defaultSFKey)) {
                                sf = (SessionFactory) new InitialContext().lookup(sessionFactoryKey);
                            }
                            mapSessionFactory.put(name, sf);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error(new StringBuilder("mockejb3 loadConfig error !").append(" config url :").append(url.getFile()).toString());
            throw new RuntimeException(e);
        }
    }

    public static Map<String, SessionFactory> getMapSessionFactory() {
        if (null == mapSessionFactory)
        {
            init();
        }
        return mapSessionFactory;
    }
}
